﻿using FRRJIf;

namespace RJi.FanucInterface3.Common.Internal;

internal class FanucRbtBuilder : IFanucRbtBuilder, IDisposable
{
    private const int Timeout = 300;

    private readonly Core _core = new() { TimeOutValue=Timeout };
    private readonly Dictionary<string, VariableMetadata> _inputMetadataCache = [];
    private readonly Dictionary<string, VariableMetadata> _outputMetadataCache = [];
    private readonly Dictionary<string, VariableMetadata> _primaryTableMetadataCache = [];
    private readonly Dictionary<string, VariableMetadata> _secondTableMetadataCache = [];
    private string? _hostname;
    private string? _name;

    public IFanucRbt Build()
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(_hostname, "Hostname cannot be empty");
        ArgumentException.ThrowIfNullOrWhiteSpace(_name, "Robot name cannot be empty");
        return new FanucRbt(_core,
            _hostname,
            _name,
            _primaryTableMetadataCache,
            _secondTableMetadataCache,
            _inputMetadataCache,
            _outputMetadataCache);
    }

    public void Dispose()
    {
        _core.Disconnect();
    }

    public IFanucRbtBuilder EnableAutoRefresh(int milliseconds)
    {
        throw new NotImplementedException();
    }

    public IFanucRbtBuilder SetHost(string? hostname, string? name = null)
    {
        ArgumentException.ThrowIfNullOrWhiteSpace(hostname, "Hostname cannot be empty");
        if (hostname.Contains(':'))
        {
            string?[] parts = hostname.Split(':');
            _hostname=parts[0];
            if (int.TryParse(parts[1], out var port)) _core.PortNumber=port;
        }
        else
        {
            _hostname=hostname;
        }

        _name=name??hostname;
        return this;
    }

    public IFanucRbtBuilder WithIO(Action<IRbtIOWrapper> config)
    {
        var wrapper = new RbtIOWrapper(_core, _inputMetadataCache, _outputMetadataCache);
        config(wrapper);
        return this;
    }

    public IFanucRbtBuilder WithPrimaryTable(Action<IDataTableWrapper> config)
    {
        var wrapper = new DataTableWrapper(_core.DataTable, _primaryTableMetadataCache);
        config(wrapper);
        return this;
    }

    public IFanucRbtBuilder WithSecondaryTable(Action<IDataTableWrapper> config)
    {
        var wrapper = new DataTableWrapper(_core.DataTable2, _secondTableMetadataCache);
        config(wrapper);
        return this;
    }

    public IFanucRbtBuilder WithTimeout(int milliseconds)
    {
        if (milliseconds<Timeout)
            throw new ArgumentException($"Timeout must be at least {Timeout}ms");

        _core.TimeOutValue=milliseconds;
        return this;
    }
}